home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
components
/
flockBlogService.js
< prev
next >
Wrap
Text File
|
2007-10-18
|
47KB
|
1,467 lines
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2007
// http://flock.com
//
// This file may be used under the terms of of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const EDITOR_URL = "chrome://flock/content/blog/editor.xul";
const DEBUG = false; // set to false to suppress debug messages
const FLOCK_BLOG_CID = Components.ID('{70b6c92b-8f34-4d1c-9057-e03e10770b96}');
const OLD_SHELF_RDF_FILE = "flock_shelf.rdf";
const OLD_BLOG_RDF_FILE = "flock_blog.rdf";
const OLD_BLOG_RDF_FILE_RELIC = "flock_blog_old.rdf";
const FLOCK_BLOG_CONTRACTID = '@flock.com/flock-blog;1';
const FLOCK_DRAFTS_ROOT = 'http://flock.com/rdf#DraftsRoot';
const FLOCK_RECOVERY_ROOT = 'http://flock.com/rdf#RecoveryRoot';
const FLOCK_UNPUBLISHED_ROOT = 'http://flock.com/rdf#UnpublishedRoot';
const BLOG_CONTENT_FILE = 'blogdrafts.sqlite';
var gBlogStorage = null;
function BlogAPIDetector() {
this.mReq = null;
this.mTitle = null;
}
BlogAPIDetector.prototype.getTitle =
function() {
return this.mTitle;
}
BlogAPIDetector.prototype.doRequest =
function(listener, url, processor) {
var inst = this;
var rootUrl = 'http://'+url.split('/')[2];
this.mReq = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest);
this.mReq.onreadystatechange = function (aEvt) {
try {
if(inst.mReq.readyState == 4) {
if(inst.mReq.status == 200) {
// debug(inst.mReq.responseText + "\n");
try {
processor(listener, rootUrl, inst);
}
catch(e) {
debug("Error "+e+" "+e.fileName+" line "+e.lineNumber+"\n");
listener.onError(e);
}
}
else {
debug("\nRESPONSE\n" + inst.mReq.responseText);
listener.onError(inst.mReq.status);
}
}
}
catch(e) {
debug("Error "+e+" "+e.fileName+" line "+e.lineNumber+"\n");
listener.onError(-1);
}
}
this.mReq.open('GET', url, true);
this.mReq.send(null);
}
BlogAPIDetector.prototype.onHomePage =
function (listener, rootUrl, inst)
{
// The following code is to clean up dirty html to make it parser
// friendly
var req = inst.mReq;
var text = req.responseText;
text = text.replace(/[\r\n]/g,"");
if(text.match(/<title.*>(.+?)</)) {
inst.mTitle = RegExp.$1;
}
var linkObj = function () {
}
linkObj.prototype = {
href:null,
rel:null,
type:null,
title:null,
QueryInterface: function (iid) {
if (!iid.equals(Ci.flockIBlogLink))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
}
}
var linklist = new Array();
var R = /<link.+?>/g;
var ar = R.exec(text);
while(ar) {
var cur = ar[0] + "";
var link = new linkObj();
if(cur.match(/href=\"(.+?)\"/)) {
link.href = RegExp.$1;
}
if(cur.match(/rel=\"(.+?)\"/)) {
link.rel = RegExp.$1;
}
if(cur.match(/title=\"(.+?)\"/)) {
link.title = RegExp.$1;
}
if(cur.match(/type=\"(.+?)\"/)) {
link.type = RegExp.$1;
}
linklist.push(link);
ar = R.exec(text);
}
var blogService = Cc[FLOCK_BLOG_CONTRACTID].getService(Ci.flockIBlogService);
var accountList = new Array();
var webServices = blogService.services;
while(webServices.hasMoreElements()) {
var service = webServices.getNext();
service.QueryInterface(Ci.flockICustomBlogWebService);
// Clone the array because our simpleEnumerator destroy it
var linklistClone = new Array();
for (i = 0; i < linklist.length; i++)
linklistClone[i] = linklist[i];
var account = service.detectAccount(rootUrl, simpleEnumerator(linklistClone));
if (account) {
debug(" ==> we found support for "+service.shortName+"\n");
accountList.push(account);
}
else {
debug(" xxx "+service.shortName+" support not found for this blog\n");
}
}
// Let's look in the RSD before we use something else
var rsd = null;
for (i = 0; i < linklist.length; i++) {
var link = linklist[i];
if (link.title=="RSD" || link.type=="application/rsd+xml") {
debug("We found a RSD!\n"+link.href+"\n");
rsd = link;
}
}
if (rsd) {
var xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance (Ci.nsIXMLHttpRequest);
xhr.open ('GET', rsd.href, true);
xhr.onreadystatechange = function (aEvent) {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
// Error
listener.onResult(null);
return;
}
var dom = xhr.responseXML;
if(!dom) {
// FIXME: Parse responseText is responseXML is not present (= bad XML)
//var parser = new DOMParser();
//dom = parser.parseFromString(req.responseText,"text/xml");
debug("No dom!!\n");
listener.onResult(null);
return;
}
var apis = dom.getElementsByTagName("api");
var prefApi = null;
var apiList = [];
for(var i=0;i<apis.length;++i) {
var api = {
api: apis[i].getAttribute("name").toLowerCase().replace(/\s/g,""),
apiLink: apis[i].getAttribute("apiLink"),
preferred: apis[i].getAttribute("preferred").toLowerCase(),
blogid: apis[i].getAttribute("blogID")
}
apiList.push(api);
if (api.preferred == 'true')
prefApi = api;
}
if (prefApi) {
var svc = blogService.getAPIFromShortname(prefApi.api);
debug("prefApi: looking for the service having shortname {"+prefApi.api+"}\n");
if (svc) {
listener.onResult(prefApi);
return;
}
}
while (apiList.length > 0) {
var currentApi = apiList.shift();
debug("looking for the service having shortname {"+currentApi.api+"}\n");
var svc = blogService.getAPIFromShortname(currentApi.api);
if (svc) {
listener.onResult(currentApi);
return;
}
}
// We couldn't find any supported API in the RSD. Loop in what we had before?
listener.onResult(null);
}
}
xhr.send (null);
}
else { // No RSD
if (accountList.length > 0) {
// Return the first account in the list
listener.onResult(accountList[0]);
}
else {
listener.onResult(null);
}
}
}
BlogAPIDetector.prototype.detect =
function(listener, url)
{
this.doRequest(listener, url, this.onHomePage);
}
function BlogDraft () {
}
BlogDraft.prototype = {
getInterfaces: function (count) {
var interfaceList = [Components.interfaces.flockIBlogDraft, Components.interfaces.nsIClassInfo];
count.value = interfaceList.length;
return interfaceList;
},
QueryInterface: function (iid) {
if (!iid.equals(Components.interfaces.flockIBlogDraft))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
getHelperForLanguage: function (count) {return null;}
}
function createStatement(dbconn, sql) {
var stmt = dbconn.createStatement(sql);
var wrapper = Cc["@mozilla.org/storage/statement-wrapper;1"]
.createInstance(Ci.mozIStorageStatementWrapper);
wrapper.initialize(stmt);
return wrapper;
}
function BlogStorage() {
var dbfile = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties).get('ProfD', Ci.nsIFile);
dbfile.append(BLOG_CONTENT_FILE);
var storageService = Cc['@mozilla.org/storage/service;1']
.getService(Ci.mozIStorageService);
this._DBConn = storageService.openDatabase(dbfile);
var drafts_schema = "id INTEGER PRIMARY KEY, lastupdate INTEGER, title STRING, " +
"content STRING, tags STRING, blog STRING DEFAULT ''";
var recovery_schema = 'id INTEGER PRIMARY KEY, lastupdate INTEGER, title STRING, ' +
'content STRING, tags STRING';
try {
this._DBConn.createTable('drafts', drafts_schema);
this._DBConn.createTable('recovery', recovery_schema);
}
catch (e) { }
this._getDraftsFrom = createStatement(this._DBConn,
'SELECT * FROM drafts WHERE blog = :blog');
this._getDraft = createStatement(this._DBConn,
'SELECT * FROM drafts WHERE id = :id');
this._replaceDraft = createStatement(this._DBConn,
'REPLACE INTO drafts (id, lastupdate, title, content, tags) ' +
'VALUES (:id, :lastupdate, :title, :content, :tags)');
this._removeDraft = createStatement(this._DBConn,
'DELETE FROM drafts where id = :id');
this._setDraftBlog = createStatement(this._DBConn,
'UPDATE drafts SET blog=:blog WHERE id=:id');
this._replaceRecovery = createStatement(this._DBConn,
'REPLACE INTO recovery (id, lastupdate, title, content, tags) ' +
'VALUES (:id, :lastupdate, :title, :content, :tags)');
this._removeRecovery = createStatement(this._DBConn,
'DELETE FROM recovery where id = :id');
this._getAllRecovery = createStatement(this._DBConn,
'SELECT * FROM recovery');
this._emptyRecovery = createStatement(this._DBConn,
'DELETE FROM recovery');
}
BlogStorage.prototype = {
deleteDraft: function BS_deleteDraft(id) {
this._removeDraft.params.id = id;
this._removeDraft.step();
this._removeDraft.reset();
},
deleteRecovery: function BS_deleteRecovery(id) {
this._removeRecovery.params.id = id;
this._removeRecovery.step();
this._removeRecovery.reset();
},
emptyRecovery: function BS_emptyRecovery() {
this._emptyRecovery.step();
this._emptyRecovery.reset();
},
saveDraft: function FS_saveDraft(id, lastupdate, title, content, tags) {
var pp = this._replaceDraft.params;
pp.id = id;
pp.lastupdate = lastupdate;
pp.title = title;
pp.content = content;
pp.tags = tags;
this._replaceDraft.step();
this._replaceDraft.reset();
},
setDraftBlog: function FS_setDraftBlog(id, blog) {
var pp = this._setDraftBlog.params;
pp.id = id;
pp.blog = blog;
this._setDraftBlog.step();
this._setDraftBlog.reset();
},
saveRecovery: function FS_saveRecovery(id, lastupdate, title, content, tags) {
var pp = this._replaceRecovery.params;
pp.id = id;
pp.lastupdate = lastupdate;
pp.title = title;
pp.content = content;
pp.tags = tags;
this._replaceRecovery.step();
this._replaceRecovery.reset();
},
getDraftsFrom: function FS_getDraftsFrom(blog) {
var result = [];
this._getDraftsFrom.reset();
var pp = this._getDraftsFrom.params;
pp.blog = blog;
while (this._getDraftsFrom.step()) {
var draft = new BlogDraft();
draft.id = this._getDraftsFrom.row['id'];
draft.lastupdate = this._getDraftsFrom.row['lastupdate'];
draft.title = this._getDraftsFrom.row['title'];
draft.content = this._getDraftsFrom.row['content'];
draft.tags = this._getDraftsFrom.row['tags'];
result.push(draft);
}
this._getDraftsFrom.reset();
return result;
},
getAllRecovery: function FS_getAllRecovery() {
var result = [];
this._getAllRecovery.reset();
while (this._getAllRecovery.step()) {
var recovery = new BlogDraft();
recovery.id = this._getAllRecovery.row['id'];
recovery.lastupdate = this._getAllRecovery.row['lastupdate'];
recovery.title = this._getAllRecovery.row['title'];
recovery.content = this._getAllRecovery.row['content'];
recovery.tags = this._getAllRecovery.row['tags'];
result.push(recovery);
}
this._getAllRecovery.reset();
return result;
},
getDraft: function FS_getDraft(draftid) {
var draft = null;
this._getDraft.reset();
this._getDraft.params.id = draftid;
if (this._getDraft.step()) {
draft = new BlogDraft();
draft.id = this._getDraft.row['id'];
draft.lastupdate = this._getDraft.row['lastupdate'];
draft.title = this._getDraft.row['title'];
draft.content = this._getDraft.row['content'];
draft.tags = this._getDraft.row['tags'];
}
this._getDraft.reset();
return draft;
},
beginTransaction: function FS_beginTransation() {
this._DBConn.beginTransaction();
},
commitTransaction: function FS_commitTransation() {
this._DBConn.commitTransaction();
},
rollbackTransaction: function FS_rollbackTransation() {
this._DBConn.rollbackTransaction();
},
_getData: function FS__getData(id, stmt, field) {
stmt.reset();
stmt.params.id = id;
var data = null;
if (stmt.step())
data = stmt.row[field];
stmt.reset();
return data;
}
}
function flockBlogService() {
// For an observer on flock-data-ready for import
var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
obs.addObserver(this, 'flock-data-ready', false);
this.acUtils = Cc["@flock.com/account-utils;1"].getService(Ci.flockIAccountUtils);
this.initialized = false;
}
flockBlogService.prototype.init =
function()
{
if (this.initialized)
return;
gBlogStorage = new BlogStorage();
this._coop = Cc["@flock.com/singleton;1"]
.getService(Ci.flockISingleton)
.getSingleton("chrome://flock/content/common/load-faves-coop.js")
.wrappedJSObject;
if (!this.needsMigration(null)) {
var prefsService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
var blogBranch = prefsService.getBranch("flock.blog.");
var mozstorage = false;
try {
mozstorage = blogBranch.getBoolPref("mozstorage");
} catch(e) { /* The pref is not set yet */ }
if (!mozstorage) {
var draftsRoot = this._coop.get(FLOCK_DRAFTS_ROOT);
if (draftsRoot) {
// Migrate from RDF to mozstorage (0.9.0 => 0.9.1)
var folders = draftsRoot.children.enumerate();
while (folders.hasMoreElements()) {
var folder = folders.getNext();
var blogid = "";
if (!folder.id().match('UnpublishedRoot')) {
blogid = folder.id().split(":folder:").pop();
}
var drafts = folder.children.enumerate();
while (drafts.hasMoreElements()) {
var draft = drafts.getNext();
// Add the draft to BlogStorage
var draftid = this.saveDraft(null, draft.name, draft.content, draft.tags);
this.moveTo(draftid, blogid);
// Then remove it from RDF
folder.children.remove(draft);
draft.destroy();
}
draftsRoot.children.remove(folder);
folder.destroy();
}
draftsRoot.destroy();
}
blogBranch.setBoolPref("mozstorage", true);
}
}
this.mName2ServiceMap = {};
this.mService2NameMap = {};
// Logger
this.logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger);
this.logger.init("blogservice");
// Add Technorati.com on first run
var prefsService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
var blogBranch = prefsService.getBranch("flock.blog");
try {
var firstRun = blogBranch.getIntPref("firstRun");
} catch(e) {}
if (!firstRun) {
// TODO
//this.addNotification("http://www.technorati.com")
//blogBranch.setIntPref("firstRun", 1);
//blogBranch.setBoolPref("notify", true);
}
// Search for registered blog web services
var catmgr = Cc["@mozilla.org/categorymanager;1"]
.getService (Ci.nsICategoryManager);
var enum_ = catmgr.enumerateCategory("flockICustomBlogWebService");
while(enum_.hasMoreElements()) {
var obj = enum_.getNext();
supportsString = obj.QueryInterface(Ci.nsISupportsCString);
var shortName = supportsString.toString();
var cid = catmgr.getCategoryEntry("flockICustomBlogWebService", shortName);
var svc = Cc[cid].getService(Ci.flockICustomBlogWebService);
this.registerAPI(svc, shortName);
}
this.initialized = true;
}
//flockIMigratable
flockBlogService.prototype.__defineGetter__("migrationName",
function flockBlogService_getter_migrationName() {
return "Blogging Accounts";
});
flockBlogService.prototype.needsMigration =
function (oldVersion)
{
var oldShelfFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
oldShelfFile.append(OLD_SHELF_RDF_FILE);
var oldBlogFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
oldBlogFile.append(OLD_BLOG_RDF_FILE);
var relicBlogFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
relicBlogFile.append(OLD_BLOG_RDF_FILE_RELIC);
// only migrate if the old favorites rdf file exists
// FIXME: after the flock_favorites.rdf file is renamed to flock_favorites_old.rdf
// flock_favorites.rdf is created again in the same dir. so we need the 2nd
// condition in the IF to stop migration from happening again
if(oldBlogFile.exists() && !relicBlogFile.exists()) {
return true;
}
return false;
}
flockBlogService.prototype.startMigration =
function(oldVersion, aFlockMigrationProgressListener)
{
this.init();
var shelf_svc = Cc['@mozilla.org/rdf/datasource;1?name=flock-shelf'].getService(Ci.flockIShelfService);
var oldShelfFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
oldShelfFile.append(OLD_SHELF_RDF_FILE);
var oldBlogFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
oldBlogFile.append(OLD_BLOG_RDF_FILE);
var relicBlogFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
relicBlogFile.append(OLD_BLOG_RDF_FILE_RELIC);
var ctxt = {
listener: aFlockMigrationProgressListener,
oldShelfFile: oldShelfFile,
oldBlogFile: oldBlogFile
};
if (oldBlogFile.exists())
ctxt.listener.onUpdate(0, 'Migrating blog settings');
return { wrappedJSObject: ctxt };
}
flockBlogService.prototype.finishMigration =
function(ctxtWrapper)
{
}
flockBlogService.prototype.doMigrationWork =
function(ctxtWrapper)
{
var ctxt = ctxtWrapper.wrappedJSObject;
if (!ctxt.oldBlogFile.exists())
return false;
if (!ctxt.blogMigrator)
ctxt.blogMigrator = this._migrateBlogs(ctxt);
if (ctxt.blogMigrator.next())
ctxt.blogMigrator = null;
return Boolean(ctxt.blogMigrator);
}
flockBlogService.prototype._migrateBlogs =
function(ctxt)
{
var blogsvc = this;
var acUtils = Cc["@flock.com/account-utils;1"].getService(Ci.flockIAccountUtils);
function createAccountAndBlog (aServiceId, aServiceUrn, aUsername, aPassword, aBlogName, aBlogid, aUrl, aApilink) {
var svc = Cc[aServiceId].getService(Ci.flockIWebService);
svc.init();
acUtils.setPassword(svc.urn+":"+aUsername, aUsername, aPassword);
var accountURN = svc.urn+":"+aUsername;
var account = new blogsvc._coop.Account(accountURN, {
name: aUsername,
serviceId: aServiceId,
service: blogsvc._coop.get(aServiceUrn),
accountId: aUsername,
favicon: svc.icon,
URL: svc.url
});
blogsvc._coop.accounts_root.children.addOnce(account);
var theCoopBlog = new blogsvc._coop.Blog(accountURN+":"+aBlogid, {
name: aBlogName,
title: aBlogName,
blogid: aBlogid,
URL: aUrl,
apiLink: aApilink
});
account.children.addOnce(theCoopBlog);
}
var rdfs = Cc["@mozilla.org/rdf/rdf-service;1"].getService (Ci.nsIRDFService);
var ios = Cc['@mozilla.org/network/io-service;1'].getService (Ci.nsIIOService);
var ds = rdfs.GetDataSourceBlocking(ios.newFileURI(ctxt.oldBlogFile).spec);
var accountsRes = rdfs.GetResource("urn:flock:blog:settings");
var container = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
container.Init(ds, accountsRes);
var children = container.GetElements();
this.logger.info("Start migration of the blog accounts");
while (children.hasMoreElements()){
var child = children.getNext().QueryInterface(Ci.nsIRDFResource);
var apiRes = rdfs.GetResource(child.ValueUTF8 + ":api");
var nameRes = rdfs.GetResource("http://www.flock.com/rdf#title");
var name = ds.GetTarget(child, nameRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
this.logger.info("Found the blog: "+name+" for import");
ctxt.listener.onUpdate(0, "Migrating " + name);
yield false;
var urlRes = rdfs.GetResource("http://www.flock.com/rdf#url");
var url = ds.GetTarget(child, urlRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
var blogidRes = rdfs.GetResource("http://www.flock.com/rdf#blogid");
var blogid = ds.GetTarget(apiRes, blogidRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
var apilinkRes = rdfs.GetResource("http://www.flock.com/rdf#apiLink");
var apilink = ds.GetTarget(apiRes, apilinkRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
// Get the username/password...
var usernameRes = rdfs.GetResource("http://www.flock.com/rdf#username");
var username = ds.GetTarget(child, usernameRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
var password = "";
this.logger.info(" Username = "+username);
if (username != "") {
var pwhostRes = rdfs.GetResource("http://www.flock.com/rdf#pwhost");
var pwhost = ds.GetTarget(child, pwhostRes, true).QueryInterface(Ci.nsIRDFLiteral).Value;
var password = getPassword(pwhost, username)
}
if (password == null || password == "") {
// The password was not stored or we couldn't find it
this.logger.info(" The password seems to be empty/unknown, let's ask the user");
var promptService = Cc['@mozilla.org/embedcomp/prompt-service;1'].getService(Ci.nsIPromptService);
var winMediator = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
var theUsername = {value: username};
var thePassword = {value: password};
promptService.promptUsernameAndPassword (
winMediator.getMostRecentWindow('navigator:browser'),
"Blog Account Import",
"Please enter your login information for "+name+"\n("+url+")",
theUsername, thePassword,
null, {value: false}
);
username = theUsername.value;
password = thePassword.value;
}
this.logger.info(" We finally have "+username+" and "+password);
// The user pressed cancel or gave a blank password => don't add the blog
if (password == null || password == "")
break;
// Now we can create the blog
if (url.match(/wordpress\.com/)) {
createAccountAndBlog ('@flock.com/people/wordpress;1', 'urn:wordpress:service', username, password,
name, blogid, url, apilink);
}
else if (url.match(/livejournal\.com/)) {
apilink = 'http://www.livejournal.com/interface/xmlrpc';
createAccountAndBlog ('@flock.com/people/livejournal;1', 'urn:livejournal:service', username, password,
name, blogid, url, apilink);
}
else if (url.match(/blogspot\.com/)) {
createAccountAndBlog ('@flock.com/people/blogger;1', 'urn:blogger:service', username, password,
name, name, url, apilink);
}
else if (url.match(/typepad\.com/)) {
createAccountAndBlog ('@flock.com/blog/typepad;1', 'urn:typepad:service', username, password,
name, blogid, url, apilink);
}
else { // Custom blog
try {
var apiRes = rdfs.GetResource("http://www.flock.com/rdf#api");
var api = ds.GetTarget(child, apiRes, true).QueryInterface(Ci.nsIRDFResource);
var apinameRes = rdfs.GetResource("http://www.flock.com/rdf#apiname");
var apiname = ds.GetTarget(api, apinameRes, true).QueryInterface(Ci.nsIRDFLiteral);
var blogidRes = rdfs.GetResource("http://www.flock.com/rdf#blogid");
var blogid = ds.GetTarget(api, blogidRes, true).QueryInterface(Ci.nsIRDFLiteral);
var apiLinkRes = rdfs.GetResource("http://www.flock.com/rdf#apiLink");
var apiLink = ds.GetTarget(api, apiLinkRes, true).QueryInterface(Ci.nsIRDFLiteral);
// Create a custom account...
var customURN = "urn:flock:customblog:"+name;
if (!this._coop.Account.exists (customURN)) {
var custom = new this._coop.Account(customURN, {
name : name,
accountId : username,
serviceId: '@flock.com/blog/service/'+apiname.Value+';1',
URL : url,
favicon: 'http://'+url.split('/')[2]+'/favicon.ico'
});
var root = this._coop.get("http://flock.com/rdf#AccountsRoot");
root.children.add(custom);
}
// ...save the password in the password manager...
var blogURN = customURN+":"+name;
var acUtils = Cc["@flock.com/account-utils;1"].getService(Ci.flockIAccountUtils);
acUtils.setPassword(customURN, username, password);
// ...and create a new blog as a child
theCoopBlog = new this._coop.Blog(blogURN, {
name: name,
title: name,
blogid: blogid.Value,
URL: url,
apiLink: apiLink.Value,
});
custom.children.addOnce(theCoopBlog);
}
catch(e) {
debug(e);
}
}
}
// Import web snippets (shelf)
// debug("Import web snippets\n");
var shelf_svc = Cc['@mozilla.org/rdf/datasource;1?name=flock-shelf'].getService(Ci.flockIShelfService);
var shelfDS = rdfs.GetDataSourceBlocking(ios.newFileURI(ctxt.oldShelfFile).spec);
var shelfRes = rdfs.GetResource("urn:flock:shelf:objects");
var container = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
container.Init(shelfDS, shelfRes);
var importFolderId;
var children = container.GetElements();
while (children.hasMoreElements()){
var child = children.getNext().QueryInterface(Ci.nsIRDFResource);
var nameRes = rdfs.GetResource("http://www.flock.com/rdf/shelf#title");
var name = shelfDS.GetTarget(child, nameRes, true).QueryInterface(Ci.nsIRDFLiteral);
var contentRes = rdfs.GetResource("http://www.flock.com/rdf/shelf#content");
var content = shelfDS.GetTarget(child, contentRes, true).QueryInterface(Ci.nsIRDFLiteral);
var urlRes = rdfs.GetResource("http://www.flock.com/rdf/shelf#url");
var url = shelfDS.GetTarget(child, urlRes, true).QueryInterface(Ci.nsIRDFLiteral);
var typeRes = rdfs.GetResource("http://www.flock.com/rdf/shelf#type");
var type = shelfDS.GetTarget(child, typeRes, true).QueryInterface(Ci.nsIRDFLiteral);
var myType;
if (type.Value == "note") {
// The "note" type is deprecated
myType = "document";
} else {
myType = type.Value;
}
debug(importFolderId+"\n");
ctxt.listener.onUpdate(0, 'Importing clipping: ' + name.Value);
shelf_svc.insert(name.Value, content.Value, url.Value, myType, -1, null);
}
// debug("Done with 'Import web snippets'\n");
// Import blog posts
var prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService)
.getBranch("flock.blog.");
var init_dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
try {
var value = prefs.getComplexValue("saveLocation", Ci.nsISupportsString).data;
} catch(e) {}
if (value) {
init_dir.initWithPath(value);
var importDraftsFolderId;
var enum = init_dir.directoryEntries;
while (enum.hasMoreElements()) {
var file = enum.getNext().QueryInterface(Ci.nsILocalFile);
try {
// Get the content of the file
var instream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
var scriptinstream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
instream.init(file, 0x01, 00400 | 00200 | 00040 | 00004, 0);
scriptinstream.init(instream);
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var result = scriptinstream.read(scriptinstream.available());
var finalresult; // Mark is getting an exception around here
finalresult = converter.ConvertToUnicode(result);
finalresult += converter.Finish();
scriptinstream.close();
// Separate the title from the content
var theTitle = finalresult.substring(0, finalresult.indexOf('\n'));
theTitle = theTitle.replace(/<h1>/, '').replace(/<\/h1>/, '');
var theBody = finalresult.substring(finalresult.indexOf('\n')+1, finalresult.length);
// Add to the drafts
var newId = this.saveDraft(null, theTitle, theBody, "");
this.moveTo(newId, "imported");
}
catch(e) {
// TODO: give feedback to the user, saying we failed to import one draft
debug("**** Error while importing the blog draft: "+file.path+". I will just ignore this draft and go on.\n\n"+e+"\n");
}
}
}
// Set this pref to prevent 0.9.0 => 0.9.1 migration to happen
prefs.setBoolPref("mozstorage", true);
// rename the file and delete the old copy
rdfs.UnregisterDataSource(ds);
ds = null;
ctxt.oldBlogFile.moveTo(null, OLD_BLOG_RDF_FILE_RELIC);
yield true;
}
// nsIObserver
flockBlogService.prototype.observe =
function(subject, topic, state)
{
switch (topic) {
case 'flock-data-ready':
var obs = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
obs.removeObserver(this, 'flock-data-ready');
this.init();
return;
}
}
// nsISimpleEnumerator implementation
function simpleEnumerator (aArray)
{
aArray.hasMoreElements = function () {
return this.length != 0;
}
aArray.getNext = function () {
var rval = this.shift ();
return rval;
}
return aArray;
}
// nsIStringEnumerator implementation
function stringEnumerator (aArray)
{
aArray.hasMore = function () {
return this.length != 0;
}
aArray.getNext = function () {
var rval = this.shift ();
return rval;
}
return aArray;
}
loadLibraryFromSpec('chrome://browser/content/flock/contrib/rdfds.js');
function loadLibraryFromSpec(aSpec)
{
var loader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
loader.loadSubScript(aSpec);
}
function getPassword(aHost, aUsername)
{
var psm = Cc["@mozilla.org/passwordmanager;1"].getService(Ci.nsIPasswordManager);
var enum = psm.enumerator;
while(enum.hasMoreElements()) {
var pw = enum.getNext();
pw = pw.QueryInterface(Ci.nsIPassword);
if(pw.host==aHost && aUsername==pw.user) {
return pw.password;
}
}
return null;
}
// Ensure that the "recent" list as no more than BLOG_RECENT_COUNT elements
flockBlogService.prototype.cleanRecent = function () {
debug("*** flockBlogService.cleanRecent: NOT IMPLEMENTED. DO IT NOW!! ***\n");
}
// the flockIBlogService implementation
flockBlogService.prototype.accountExists = function (aTitle) {
var accounts = this._coop.Blog.find({ title: aTitle });
return (accounts.length > 0);
}
flockBlogService.prototype.accountCount = function () {
var count = 0;
var accounts = this._coop.get('http://flock.com/rdf#AccountsRoot');
var enum = accounts.children.enumerate();
while (enum.hasMoreElements()) {
var account = enum.getNext();
if (!account) continue; // getNext() can return NULL when hasMoreElements() is TRUE.
var enum2 = account.children.enumerate();
while (enum2.hasMoreElements())
if (enum2.getNext().isInstanceOf(this._coop.Blog))
++count;
}
return count;
}
flockBlogService.prototype.getAccountList = function () {
var result = new Array();
var accounts = this._coop.get('http://flock.com/rdf#AccountsRoot');
var enum = accounts.children.enumerate();
while (enum.hasMoreElements()) {
var account = enum.getNext();
if (!account) continue; // getNext() can return NULL when hasMoreElements() is TRUE.
var enum2 = account.children.enumerate();
while (enum2.hasMoreElements()) {
var child = enum2.getNext();
if (child.isInstanceOf(this._coop.Blog))
result.push(child);
}
}
return simpleEnumerator(result);
}
flockBlogService.prototype.getDefaultBlog = function () {
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch("flock.blog.");
var value = null;
try{
value = prefs.getCharPref ("defaultblog");
} catch(e) {
return "";
}
return value;
}
flockBlogService.prototype.setDefaultBlog = function (aValue) {
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch("flock.blog.");
prefs.setCharPref ("defaultblog", aValue);
}
flockBlogService.prototype.addRecent = function (aName, aFile) {
debug("*** flockBlogService.addRecent: NOT IMPLEMENTED. DO IT NOW!! ***\n");
}
flockBlogService.prototype.recentIsEmpty =
function ()
{
debug("*** flockBlogService.recentIsEmpty: NOT IMPLEMENTED. DO IT NOW!! ***\n");
}
flockBlogService.prototype.registerAPI =
function(aService, aShortname)
{
this.mName2ServiceMap[aShortname] = aService;
this.mService2NameMap[aService] = aShortname;
}
flockBlogService.prototype.getAPIFromShortname =
function(aShortname)
{
for (i in this.mName2ServiceMap) {
debug(i+": "+this.mName2ServiceMap[i]+"\n");
}
return this.mName2ServiceMap[aShortname];
}
flockBlogService.prototype.getShortnameFromAPI =
function(aService)
{
return this.mService2NameMap[aService];
}
flockBlogService.prototype.__defineGetter__('services', function ()
{
var ar = new Array();
for(var p in this.mName2ServiceMap) {
ar.push(this.mName2ServiceMap[p]);
}
var rval = {
getNext: function() {
var rval = ar.shift();
return rval;
},
hasMoreElements: function() {
return (ar.length>0);
},
}
return rval;
})
flockBlogService.prototype.getCandidatesAPI =
function(aListener, aUrl)
{
var detector = new BlogAPIDetector();
detector.detect(aListener, aUrl);
}
flockBlogService.prototype.saveAccount =
function (aParentId, aId, aBlogAccount)
{
// Get or create the coop object
var account = null;
if (aId) {
account = this._coop.get(aId);
if (!account)
account = new this._coop.Blog(aId);
}
else
account = new this._coop.Blog(aParentId+":"+aBlogAccount.username);
// Save the password in the password manager
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var uri = ios.newURI(aBlogAccount.URL, null, null);
var pwhost = "flockinternal." + uri.host;
if(aBlogAccount.username && aBlogAccount.username.length) {
var psm = Cc["@mozilla.org/passwordmanager;1"].getService(Ci.nsIPasswordManager);
psm.addUser(pwhost, aBlogAccount.username, aBlogAccount.password);
}
// Save the rest in flock-data
account.title = aBlogAccount.title;
account.name = aBlogAccount.title;
account.favicon = aBlogAccount.favicon;
account.username = aBlogAccount.username;
account.URL = aBlogAccount.URL;
account.pwhost = pwhost;
account.api = aBlogAccount.api;
account.apiLink = aBlogAccount.apiLink;
account.blogid = aBlogAccount.blogid;
account.authtoken = aBlogAccount.authtoken;
var parent = this._coop.get(aParentId);
parent.children.add(account);
}
flockBlogService.prototype.getAccount = function (aBlogID) {
if(!aBlogID) throw new Error("Error in BlogSettings.getAccount()");
var coopblog = this._coop.get(aBlogID);
var coopaccount = coopblog.getParent();
if (coopaccount) {
// var password = getPassword(coopaccount.id()+":"+coopaccount.accountId, coopaccount.accountId);
debug(" ^^^^^^^^^ Get the password for "+coopaccount.id()+"\n");
var pw = this.acUtils.getPassword(coopaccount.id());
if (pw)
var password = pw.password;
debug("++++++ Found the password: "+password+"\n");
}
var account = {
blogid: coopblog.blogid,
username: coopaccount.accountId,
password: password,
authtoken: coopblog.authtoken,
apiLink: coopblog.apiLink,
getInterfaces: function (count) {
var interfaceList = [Ci.flockIBlogAccount, Ci.nsIClassInfo];
count.value = interfaceList.length;
return interfaceList;
},
QueryInterface: function (iid) {
if (!iid.equals(Ci.flockIBlogAccount))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
}
}
return account;
};
flockBlogService.prototype.getBlogAPI = function (aBlogID) {
try {
var account = this._coop.get(aBlogID);
return this.getAPIFromShortname(account.api);
}
catch(e) {
debug("Caught exception: "+e+" "+e.fileName+" "+e.lineNumber+"\n");
return null;
}
};
flockBlogService.prototype.addCategory = function (aBlogID, aCategoryId, aCategoryName) {
var account = this._coop.get(aBlogID);
var enum = account.categories.enumerate();
var category = null;
while (enum.hasMoreElements()) {
var cat = enum.getNext();
if (cat.categoryId == aCategoryId)
category = cat;
}
if (!category) {
category = new this._coop.BlogCategory();
category.categoryId = aCategoryId;
}
category.name = aCategoryName;
account.categories.addOnce(category);
};
flockBlogService.prototype.flushCategories = function (aBlogAccount) {
debug("*** flockBlogService.flushCategories: DEPRECATED. DON'T USE IT!! ***\n");
};
flockBlogService.prototype.addNotification = function (aURL) {
debug("*** flockBlogService.addNotification: NOT IMPLEMENTED. DO IT NOW!! ***\n");
};
flockBlogService.prototype.removeNotification = function (aURL) {
debug("*** flockBlogService.removeNotification: NOT IMPLEMENTED. DO IT NOW!! ***\n");
};
flockBlogService.prototype.getNotifications = function () {
debug("*** flockBlogService.getNotifications: NOT IMPLEMENTED. DO IT NOW!! ***\n");
return stringEnumerator([]);
};
flockBlogService.prototype._openBlogEditor =
function (aParams) {
// Recover if needed
var needRecovery = false;
if (!this.editorIsOpen()) {
var _enum = this.getAllRecovery();
if (_enum.hasMoreElements()) // There is at least one recovered draft
needRecovery = true;
}
if (needRecovery) {
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow('navigator:browser');
win.openDialog("chrome://flock/content/blog/blogRecovery.xul",
"openRecovery", "chrome,modal,centerscreen", null);
}
var ww = Cc['@mozilla.org/embedcomp/window-watcher;1'].getService(Ci.nsIWindowWatcher);
return ww.openWindow(null, EDITOR_URL, "_blank", "chrome,close,titlebar,resizable=yes,toolbar=no,dialog=no,scrollbars=yes", aParams);
}
flockBlogService.prototype.openPost =
function (aId) {
var windowMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
// See if the post is not already open
var oldWin = null;
var singleUploadWindow = false;
var allWindows = windowMediator.getEnumerator(null);
debug("Looking for {"+aId+"}\n");
while (allWindows.hasMoreElements() && !oldWin) {
var win = allWindows.getNext();
if (win.gDraftId && (win.gDraftId == aId)) {
oldWin = win;
}
}
if (oldWin) { // Bring the existing window to the front
oldWin.focus();
}
else { // Open a new window
var params = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(Ci.nsIDialogParamBlock);
params.SetNumberStrings(4);
params.SetString(0, aId);
params.SetString(1, "");
params.SetString(2, "");
params.SetString(3, "");
this._openBlogEditor(params);
}
}
flockBlogService.prototype.openEditor =
function (aTitle, aContent, aTags) {
var setup = 1; // Default to "Cancel"
if (this.accountCount() == 0) {
// Tell the user to configure an account
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow('navigator:browser');
var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService);
var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
.getService(Ci.nsIStringBundleService);
var sb = sbs.createBundle("chrome://flock/locale/blog/blog.properties");
var brand = sbs.createBundle("chrome://branding/locale/brand.properties");
var flags = Ci.nsIPromptService.BUTTON_TITLE_IS_STRING *
Ci.nsIPromptService.BUTTON_POS_0 +
Ci.nsIPromptService.BUTTON_TITLE_CANCEL *
Ci.nsIPromptService.BUTTON_POS_1 +
Ci.nsIPromptService.BUTTON_TITLE_IS_STRING *
Ci.nsIPromptService.BUTTON_POS_2;
var title = sb.GetStringFromName("flock.blog.account.req.title");
var button1 = sb.GetStringFromName("flock.blog.account.req.setupButton");
var appName = brand.GetStringFromName("brandShortName");
var button3 = sb.GetStringFromName("flock.blog.account.req.continueButton");
var substitutions = [button1, appName, button3];
var bodyText = sb.formatStringFromName("flock.blog.account.req.text",
substitutions,
substitutions.length);
setup = ps.confirmEx(win,
title,
bodyText,
flags,
button1,
null,
button3,
null,
{});
}
else {
setup = 2;
}
switch (setup) {
case 0:
// "Setup Account"
win.flock_blogLaunchSettings();
break;
case 2:
// "Continue"
//dump("aContent = "+aContent+"\n");
var params = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(Ci.nsIDialogParamBlock);
params.SetNumberStrings(4);
params.SetString(0, "");
params.SetString(1, aTitle?aTitle:"");
params.SetString(2, aContent?aContent:"");
params.SetString(3, aTags?aTags:"");
return this._openBlogEditor(params);
default:
// Cancel
}
return null;
}
flockBlogService.prototype.editorIsOpen =
function () {
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
return (!!wm.getMostRecentWindow("Flock:BlogEditor"));
}
flockBlogService.prototype._save =
function (aId, aTitle, aContent, aTags, aRecovery) {
var now = (new Date()).getTime();
var id = (aId && aId > 0)?aId:(now * 100 + Math.floor(Math.random() * 100));
if (aRecovery) {
gBlogStorage.saveRecovery(id, now, aTitle, aContent, aTags);
} else {
gBlogStorage.saveDraft(id, now, aTitle, aContent, aTags);
}
return id;
}
flockBlogService.prototype.saveDraft =
function (aId, aTitle, aContent, aTags) {
return this._save(aId, aTitle, aContent, aTags, false);
}
flockBlogService.prototype.saveRecovery =
function (aId, aTitle, aContent, aTags) {
return this._save(aId, aTitle, aContent, aTags, true);
}
flockBlogService.prototype.getDraft =
function flockBlogService_getDraft (aDraftId) {
return gBlogStorage.getDraft(aDraftId);
}
flockBlogService.prototype.getDraftsFrom =
function flockBlogService_getDraftsFrom (aBlogId) {
var drafts = gBlogStorage.getDraftsFrom (aBlogId);
return simpleEnumerator(drafts);
}
flockBlogService.prototype.moveTo =
function flockBlogService_moveTo (aId, aBlogId) {
gBlogStorage.setDraftBlog(aId, aBlogId);
}
flockBlogService.prototype.removeDraft =
function (aId) {
gBlogStorage.deleteDraft(aId);
}
flockBlogService.prototype.removeRecovery =
function (aId) {
gBlogStorage.deleteRecovery(aId);
}
flockBlogService.prototype.looseRecovery =
function () {
gBlogStorage.emptyRecovery();
}
flockBlogService.prototype.getAllRecovery =
function flockBlogService_getAllRecovery () {
var recoveries = gBlogStorage.getAllRecovery ();
return simpleEnumerator(recoveries);
}
flockBlogService.prototype.flags = Ci.nsIClassInfo.SINGLETON;
flockBlogService.prototype.classDescription = "Flock Blog Service";
flockBlogService.prototype.getInterfaces = function (count) {
var interfaceList = [Ci.flockIBlogService, Ci.flockIMigratable,
Ci.nsIObserver, Ci.nsIClassInfo];
count.value = interfaceList.length;
return interfaceList;
}
flockBlogService.prototype.getHelperForLanguage = function (count) {return null;}
// the nsISupports implementation
flockBlogService.prototype.QueryInterface =
function (iid) {
if (!iid.equals(Ci.flockIBlogService) &&
!iid.equals(Ci.flockIMigratable) &&
!iid.equals(Ci.nsIClassInfo) &&
!iid.equals(Ci.nsIObserver) &&
!iid.equals(Ci.nsISupports))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
}
// Module implementation
var BlogModule = new Object();
BlogModule.registerSelf =
function (compMgr, fileSpec, location, type)
{
compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
compMgr.registerFactoryLocation(FLOCK_BLOG_CID,
"Flock Blog JS Component",
FLOCK_BLOG_CONTRACTID,
fileSpec,
location,
type);
// Make the blog service a startup observer (for migration)
var categoryManager = Cc["@mozilla.org/categorymanager;1"]
.getService(Ci.nsICategoryManager);
categoryManager.addCategoryEntry("flock-startup", "Flock Blog Service", "service," + FLOCK_BLOG_CONTRACTID, true, true);
categoryManager.addCategoryEntry('flockMigratable', 'blogservice', FLOCK_BLOG_CONTRACTID, true, true);
}
BlogModule.getClassObject =
function (compMgr, cid, iid) {
if (!cid.equals(FLOCK_BLOG_CID))
throw Cr.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Ci.nsIFactory))
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
return BlogServiceFactory;
}
BlogModule.canUnload =
function(compMgr)
{
return true;
}
/* factory object */
var BlogServiceFactory = new Object();
BlogServiceFactory.createInstance =
function (outer, iid) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return (new flockBlogService()).QueryInterface(iid);
}
/* entrypoint */
function NSGetModule(compMgr, fileSpec) {
return BlogModule;
}